﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GameEngine
{
    public class PlayerObject : GameObject
    {
        #region Local Variables

        enum PlayerAction
        {
            idleSide,
            idleUp,
            idleDown,
            walkSide,
            walkUp,
            walkDown,
            use
        };


        #endregion

        #region Attributes

        public Keys Up { set; get; }
        public Keys Right { set; get; }
        public Keys Down { set; get; }
        public Keys Left { set; get; }
        public Keys Inventory { set; get; }
        public Keys GameMenu { set; get; }

        private PlayerAction currentAction = PlayerAction.idleSide;
        private float moveScale = 620.0f;

        #endregion

        #region Constructor and Initialization

        public PlayerObject(Texture2D spriteSheet)
        {

            SpriteSheet = spriteSheet;

            #region Controls

            Up = Keys.W;
            Right = Keys.D;
            Down = Keys.S;
            Left = Keys.A;
            Inventory = Keys.I;
            GameMenu = Keys.Escape;

            #endregion

            #region Animations
            AddAnimation(new Rectangle(0, 0, 128, 320), 1, PlayerAction.idleDown, false);

            AddAnimation(new Rectangle(0, 320, 128, 320), 1, PlayerAction.idleSide, false);

            AddAnimation(new Rectangle(0, 640, 128, 320), 1, PlayerAction.idleUp, false);

            AddAnimation(new Rectangle(0, 0, 128, 320), 1, PlayerAction.walkDown, false);

            AddAnimation(new Rectangle(0, 320, 128, 320), 1, PlayerAction.walkSide, false);

            AddAnimation(new Rectangle(0, 640, 128, 320), 1, PlayerAction.walkUp, false);

            //AddAnimation(new Rectangle(0, 300, 20, 20), 5, PlayerAction.use, false);
            //animations[ActionToString(PlayerAction.use)].NextAnimation = ActionToString(PlayerAction.idleSide);

            #endregion

            CollisionRectangle = new Rectangle(0, 0, 70, 12);

            drawDepth = 0.825f;
            enabled = true;

            PlayAnimation(ActionToString(currentAction));

        }

        #endregion

        #region Properties

        public Vector2 SpritePosition
        {
            get {
                return WorldLocation - new Vector2(animations[currentAnimation].FrameRectangle.Width / 2, 320);
            }
        }

        #endregion

        #region Local Methods

        private String ActionToString(PlayerAction actionName)
        {
            return actionName.ToString().Trim();
        }

        private void AddAnimation(Rectangle firstFrame, int frameCount, PlayerAction actionName, bool loopAnimation)
        {
            String sActionName = ActionToString(actionName);

            animations.Add(sActionName, new AnimationSequence(firstFrame, frameCount, loopAnimation, sActionName));
        }


        #endregion

        #region Public Methods

        public override void Update(GameTime gameTime)
        {

            PlayerAction newAction;

            switch (currentAction)
            {
                case PlayerAction.walkSide:
                    newAction = PlayerAction.idleSide;
                    break;

                case PlayerAction.idleUp:
                    newAction = PlayerAction.idleUp;
                    break;

                case PlayerAction.walkDown:
                    newAction = PlayerAction.idleDown;
                    break;
                default:
                    newAction = PlayerAction.idleSide;
                    break;
            }

            velocity = Vector2.Zero;


            #region Actions

            KeyboardState keyState = Keyboard.GetState();

            if (keyState.IsKeyDown(Left))
            {
                flipped = true;
                newAction = PlayerAction.walkSide;
                velocity = new Vector2(-moveScale, velocity.Y);
            }

            if (keyState.IsKeyDown(Right))
            {
                flipped = false;
                newAction = PlayerAction.walkSide;
                velocity = new Vector2(moveScale, velocity.Y);
            }

            if (keyState.IsKeyDown(Up))
            {
                flipped = false;
                newAction = PlayerAction.walkUp;
                velocity = new Vector2(velocity.X, -moveScale);
            }

            if (keyState.IsKeyDown(Down))
            {
                flipped = false;
                newAction = PlayerAction.walkDown;
                velocity = new Vector2(velocity.X, moveScale);
            }

            //temporär
            if (Mouse.GetState().LeftButton == ButtonState.Pressed)
            {
                flipped = false;
                newAction = PlayerAction.use;
                velocity = new Vector2(velocity.X, velocity.Y);
            }

            #endregion

            if (newAction != currentAction)
            {
                PlayAnimation(ActionToString(newAction));
            }

            base.Update(gameTime);
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            
            if (!enabled) return;

            if (animations.ContainsKey(currentAnimation))
            {
                spriteBatch.Draw(
                    SpriteSheet,
                    SpritePosition,
                    animations[currentAnimation].FrameRectangle,
                    Color.White,
                    0.0f,
                    Vector2.Zero,
                    1,
                    Effect,
                    drawDepth);
            }
        }

        #endregion

    }


    #region old Player
    
    //public class PlayerObject
    //{

    //    #region Local Variables

    //    public enum PlayerAction {
    //        Stand_Up = 0,
    //        Stand_Right,
    //        Stand_Down,
    //        Stand_Left,
    //        WalkUp,
    //        WalkRight,
    //        WalkDown,
    //        WalkLeft
    //    };

    //    int frameWidth = 128;
    //    int frameHeight = 320;
    //    int currentFrame = 0;

    //    #endregion

    //    #region Attributes

    //    public PlayerAction _currentAction;
    //    private Rectangle _collisionBox;


    //    private Vector2 PlayerOrigin;
    //    private Vector2 _collisionBoxOrigin;

    //    private Vector2 _position;

    //    private Texture2D _texture;

    //    private List<Sprite> _sprites;

    //    public Keys Up { set; get; }
    //    public Keys Right { set; get; }
    //    public Keys Down { set; get; }
    //    public Keys Left { set; get; }
    //    public Keys Inventory { set; get; }
    //    public Keys GameMenu { set; get; }

    //    #endregion

    //    #region Constructor

    //    public PlayerObject(Vector2 startPos, Texture2D texture) {
    //        this._currentAction = PlayerAction.Stand_Right;
    //        this._texture = texture;
    //        this._position = startPos;
    //        this._sprites = new List<Sprite>();
            
    //        Up = Keys.W;
    //        Right = Keys.D; 
    //        Down = Keys.S;
    //        Left = Keys.A;
    //        Inventory = Keys.I;
    //        GameMenu = Keys.Escape;
            


    //        this._collisionBox = new Rectangle(0,0, 50, 12);
    //        _collisionBoxOrigin = new Vector2(_collisionBox.Width / 2 , _collisionBox.Height / 2);
            

    //        initAnimations(frameWidth, frameHeight);
           
    //        PlayerOrigin = new Vector2(frameWidth / 2, frameHeight / 2);

            
    //    }

    //    private void initAnimations(int frameWidth, int frameHeight)
    //    {
    //        /*========== STAND ==========*/
    //        //Up
    //        _sprites.Add(new Sprite(Position,_texture, new Rectangle(2, 0, frameWidth, frameHeight),Vector2.Zero));

    //        //Side Right
    //        _sprites.Add(new Sprite(Position, _texture, new Rectangle(1, 0, frameWidth, frameHeight), Vector2.Zero));

    //        //Side Left
    //        _sprites.Add(new Sprite(Position, _texture, new Rectangle(1, 0, frameWidth, frameHeight), Vector2.Zero) { Flip = SpriteEffects.FlipVertically});

    //        //Down
    //        _sprites.Add(new Sprite(Position, _texture, new Rectangle(0, 0, frameWidth, frameHeight), Vector2.Zero));
            


    //        /*========== Walk ==========*/
    //        //Front
    //        //Side
    //        //Back


    //        /*========== Event Actions ==========*/
    //        //Grab
    //        //Talk
    //        //Push

    //    }

    //    #endregion

    //    #region Properties

    //    public Rectangle CollisionBox 
    //    {
    //        set { this._collisionBox = value; }
    //        get { return this._collisionBox; }
    //    }

    //    private Vector2 CollisionBoxOrigin 
    //    {
    //        get { return this._collisionBoxOrigin; }
    //    }

    //    private List<Sprite> Sprites
    //    {
    //        set { this._sprites = value; }
    //        get { return this._sprites; }
    //    }

    //    public Vector2 Position 
    //    {
    //        set {
    //            Vector2 NewPos = value;
    //            this._position = NewPos;

    //            Sprite currentSprite = GetCurrentAction;

    //            CollisionBox = new Rectangle((int)(NewPos.X - CollisionBoxOrigin.X), (int)(NewPos.Y - CollisionBoxOrigin.Y), CollisionBox.Width, CollisionBox.Height);

    //            Sprites.ElementAt((int)CurrentAction).Location = new Vector2(NewPos.X - frameWidth/2, NewPos.Y - currentSprite.FrameHeight);
                
    //            Console.WriteLine("CollisionBox Vector: " + CollisionBox.Location.ToString());
    //        }
    //        get { return this._position; }
    //    }

    //    public PlayerAction CurrentAction 
    //    {
    //        set { this._currentAction = value; }
    //        get { return this._currentAction; }
    //    }

    //    public Sprite GetCurrentAction 
    //    {
    //        get {
    //            return Sprites.ElementAt((int)CurrentAction);
    //        }
    //    }

    //    public int HitBoxWidth
    //    {
    //        set { _collisionBox = new Rectangle(_collisionBox.X, _collisionBox.Y, value, _collisionBox.Height); } //templösning för att se att det fungerar 
    //        get { return _collisionBox.Width; }
    //    }

    //    public int HitBoxHeight
    //    {
    //        set { _collisionBox = new Rectangle(_collisionBox.X, _collisionBox.Y, _collisionBox.Width, value); }
    //        get { return _collisionBox.Height; }
    //    }

    //    public Vector2 HitBoxOrigin 
    //    {
    //        get { return new Vector2(HitBoxWidth / 2, HitBoxHeight / 2); }
    //    }

    //    #endregion

    //    #region Local Methods

    //    private void UpdateControl(KeyboardState keyboardState)
    //    {
    //        float newX = 0;
    //        float newY = 0;
    //        float moveSpeed = 10;

    //        if (keyboardState.IsKeyDown(Up)) newY -= moveSpeed;
    //        if (keyboardState.IsKeyDown(Right)) newX += moveSpeed;
    //        if (keyboardState.IsKeyDown(Down)) newY += moveSpeed;
    //        if (keyboardState.IsKeyDown(Left)) newX -= moveSpeed;

    //        Position = new Vector2(Position.X + newX, Position.Y + newY);

    //    }

    //    #endregion

    //    #region Public Methods

    //    public virtual void Update(GameTime gameTime, KeyboardState ks)
    //    {
    //        UpdateControl(ks);
    //        Console.WriteLine(this.Position.ToString());
    //    }

    //    public virtual void Draw(SpriteBatch spriteBatch, float scale)
    //    {

    //        GetCurrentAction.Draw(spriteBatch, scale);

    //    }

    //    #endregion
    //}

    #endregion
}
